home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-03-09 | 18.9 KB | 673 lines | [TEXT/MPS ] |
- // Copyright © 1993,4 Apple Computer, Inc. All rights reserved
- //Project Data for GoodForm
-
- // application based constants
- constant kAppSymbol := '|GoodForm:PIEDTS|;
- constant kAppName := "GoodForm";
- constant kPackageName := "GoodForm:PIEDTS";
- constant kAppObject := '["Datum","Data"];
- constant kAppAll:= "All Data";
-
- // soup based constants
- constant kSoupName := kPackageName;
- constant kSoupIndexes := '[];
-
- // a default soup entry
- DefConst('kDefaultEntry, {text: "", labels: nil});
-
-
- // GetAppParams constants
- constant kMaxApplicationWidth:= 250;
- constant kMaxApplicationHeight:= 336;
-
- // Install and RemoveScripts
-
- InstallScript := func(partFrame)
- begin
- // register support for routing
- GetGlobals().routing.(kAppSymbol) := partFrame.theForm.entryRoutingFrame;
-
- // Register global find support
- AddArraySlot(findApps, kAppSymbol);
-
- // register filing support
- AddArraySlot(soupNotify, kSoupName);
- AddArraySlot(soupNotify, kAppSymbol);
- end;
-
-
- RemoveScript := func(packageFrame)
- begin
- // Unregister global find support
- SetRemove(findApps, kAppSymbol);
-
- // un-register filing support
- local soupNotifyPos:= ArrayPos(soupNotify, kAppSymbol, 0, nil);
- ArrayRemoveCount(soupNotify, soupNotifyPos - 1, 2);
-
- // un-register routing support
- RemoveSlot(GetGlobals().routing, kAppSymbol);
- end;
- // ---- End Project Data ----
-
-
- // ---- File GoodForm.t ----
-
- // Before Script for "GoodFormBase"
- // Copyright © 1993,4 Apple Computer, Inc. All rights reserved
-
- GoodFormBase :=
- {
- PutAway:
- func(item)
- // this might be called while we are not running, hense the
- // reason to check for the existance of uSoup.
- begin
- // get the entry from the system
- local newEntry := item.body;
- local theSoup := nil;
-
- // make sure we have the correct folder
- // for the labels slot
- CheckThatFolderExists(newEntry);
- if uSoup then
- theSoup := uSoup
- else
- theSoup := :RegisterCardSoup(kSoupName, kSoupIndexes,
- kAppSymbol, kAppObject);
-
- theSoup:AddToDefaultStore(newEntry); // add the entry
-
- if not uSoup then
- :UnRegisterCardSoup(kSoupName); // clean up
-
- BroadcastSoupChange(kSoupName); // tell everyone we've changed
- end,
- SetTarget:
- func(entry)
- // used by several of our methods, this function
- // sets the target and adjusts both the cursor
- // and the display appropriately
- begin
- if entry and cursor:Goto(entry) then
- Target := entry
- else
- Target:= NIL;
-
- :UpdateFieldsFromEntry(target);
- end,
- viewSetupDoneScript:
- func()
- begin
- // try to restore the old Target
- local testTarget:= :GetLastTargetFromPrefsID();
-
- if testTarget and cursor:Goto(testTarget) then
- :SetTarget(testTarget)
- else
- begin
- cursor:Reset();
- :SetTarget(cursor:Entry())
- end;
-
- // add support for Newton Connection Kit
- :AddNCKSupport();
- end,
- SaveToSoup:
- func()
- // Save Entry to Soup
- begin
- target.text := Clone(inputField.text);
- EntryChange(target);
- :SetDirty(nil);
- end,
- viewFormat: 524624,
- viewQuitScript:
- func()
- // Remember to unregister the soup, and zap the currently used
- // references here, otherwise you get into trouble when removing
- // the PCMCIA card with the app.
- begin
- // make sure we can restore the target if the card is removed
- if Target then
- prefsEntry:= EntryUniqueID(Target)
- else
- prefsEntry:= nil;
-
- // if the view is dirty, make sure the entry is changed
- if dirty then
- :SaveToSoup();
-
- // nil out all of our references and un-register the card soup
- call kUnRegisterCardSoupFunc with (kSoupName);
- uSoup:= nil;
- cursor:= nil;
- Target:= nil;
- end,
- AppAll: kAppAll,
- target: nil,
- FolderChanged:
- func(soupname, oldLabel, newLabel)
- // basic task is to assign new values to
- // the 'labels slot in each check because
- // the user has changed the name of one
- // of the folders, NOTE this can be executed
- // when this app is not running.
- begin
- local soup := GetUnionSoup(kSoupName);
- if soup then
- begin
- local localCursor := query(soup, {type: 'index,
- validTest: func(entry)
- begin
- return entry.labels = oldLabel;
- end
- });
-
- // change the labels of each entry in the soup to newLabel
- local localEntry := localCursor:Entry();
- while localEntry do
- begin
- localEntry.labels := newLabel;
- EntryChange(localEntry);
- localEntry := localCursor:Next();
- end;
-
- // tell everyone else we've done it
- BroadcastSoupChange(kSoupName);
- end;
-
- // redraw the folder tab if we are running
- if folderTab then
- folderTab:UpdateFilter(oldLabel, newLabel)
- end,
- viewFlags: 4,
- UndoDuplicateEntry:
- func(entry)
- // use the delete message and the DeleteAnEntry method
- // to crumple the view and remove the duplicate item
- begin
- inputField:Delete('DeleteAnEntry, [entry]);
- end,
- viewIdleScript:
- func()
- begin
- if dirty then
- :SaveToSoup();
- return 5000; // we will get called every 5 seconds
- end,
- AddNCKSupport:
- func()
- begin
- // get a reference to the Directory soup and another
- // reference to a cursor that points to our
- // metadata entry in the directory
- local soup := GetStores()[0]:GetSoup("Directory");
- local q := Query(Soup,
- {type: 'index,
- validTest: func(item)
- StrEqual(item.soup, kSoupName)}
- );
-
- // if our metadata is not entered there, enter it
- // should really test version of meta data
- if not q:Entry() then
- begin
- local nckMeta := Clone(nckMetaData);
- soup:Add(nckMeta);
- end
- end,
- DeleteActionScript:
- func(entry, targetView)
- begin
- if Target then
- begin
- inputField:Delete('DeleteAnEntry, [entry]); // Delete does a crumple
- AddUndoAction('undoDeleteEntry, [entry])
- end
- else
- :Notify(kNotifyAlert, EnsureInternal(kAppName),
- EnsureInternal("There is no Data to delete"));
- end,
- viewBounds: {top: 20, left: -2, right: 231, bottom: 280},
- appObject: kAppObject,
- FilingChanged:
- func()
- // basic task, decide if the target should be displayed
- // using the current filter since the user has changed
- // the way the entry is filed
- begin
- // make sure that the changes done to the labels slot
- // are flushed from the cache
- :SaveToSoup();
-
- if cursor:Goto(Target) then
- begin
- // do nothing, leave display alone
- end
- else
- begin
- cursor:Reset();
- :SetTarget(cursor:Entry()); // this displays the target
- end
- end,
- cursor:
- // keep track of the current cursor pointing at soup entries
- nil,
- FilterChanged:
- func()
- // basic task is to redraw the item(s) based
- // on the new filter selected by the user
- begin
- if Target and cursor:Goto(Target) then
- begin
- // do nothing, leave display alone
- end
- else
- begin
- // it must be filtered out, so display the first
- // non-filtered entry
- if dirty then
- :SaveToSoup();
- cursor:Reset();
- :SetTarget(cursor:Entry()); // this displays the target
- end
- end,
- labelsFilter: nil,
- ShowFoundItem:
- func(entry, finder)
- // shows the found item
- begin
- :SetTarget(entry); // just go to the one selected, present it
- end,
- viewScrollDownScript:
- func()
- begin
- // we use local variables in case the call to Next()
- // fails, and we avoid restoring the cursor
- local localCursor:= cursor:Clone();
- local localEntry:= localCursor:Next();
- if localEntry then
- begin
- if dirty then
- :SaveToSoup();
- :SetTarget(localEntry);
- end
- else
- GetRoot():SysBeep()
- end,
- viewOverviewScript:
- func()
- begin
- :Notify(kNotifyAlert, EnsureInternal(kAppName),
- EnsureInternal("This application does not support an overview mode"));
- end,
- appSymbol: kAppSymbol,
- viewJustify: 16,
- nckMetaData:
- { // The metadata description is rich and powerful. Please refer to
- // the documentation for more details which are beyond the scope of
- // this simple example.
-
- soup: kSoupName,
-
- name: kAppName,
-
- version: 1, // this code supports only version 1.0 of NCK
- // but 2.0 is backward compatible
-
- defaultDefinitions: {
- textEntry: {label: "Text Entry:", size: 100},
- },
-
- displayInfo: [ // each entry here is a slot name in the textFrame
- // and the order here is the order they will appear
- // in NCK's DataBrowser Window.
- 'textEntry,
- ],
-
- editInfo: [ // each entry here is a slot name in the textFrame
- // and the order here is the order they will appear
- // in NCK's Detail Window.
- 'textEntry,
- ],
-
- exportInfo: [ // ???
- 'textEntry,
- ],
-
- // The import() (from NCK to Newton) and the export() (from Newton
- // to NCK) functions do the actual conversion of the data. Note
- // the structure of the textFrame used by NCK, it's easiest to
- // see by looking in the export() function. The "OriginalFrame"
- // slot is actually storage for the soupFrame, and the other frames
- // store conversions of those slots in the soupFrame to a textual
- // format.
-
- import: func(textFrame)
- // converts text frame to soup entry
- begin
- if textFrame.originalFrame then
- textFrame.originalFrame.text:= "LIKE WOW MAN" // textFrame.textEntry
- else
- textFrame.originalFrame:= {text: "totally cool"};// textFrame.textEntry};
-
- textFrame.originalFrame // this is the soupFrame!!!
- end,
-
- export: func(soupFrame)
- // converts soup entry to text frame for edit/display
- begin
- local textFrame;
- textFrame:= { originalFrame: soupFrame,
- textEntry: soupFrame.text};
-
- textFrame;
- end,
- },
- SetDirty:
- func(IsDirty)
- begin
- dirty:= IsDirty;
- end,
- Find:
- func(what, results, scope, statusForm)
- begin
- if statusForm then
- statusForm:SetStatus("Searching in" && kAppName & $\u2026);
-
- // application can be closed when this call is made, so
- // get a local cursor to the soup
- local theSoup := GetUnionSoup(kSoupName);
- if theSoup then
- begin
- local theCursor := Query(theSoup, {type: 'text, text: what});
-
- if theCursor:Entry() then
- begin
- local theResult :=
- {
- _proto: GetRoot().soupFinder,
- owner: self,
- title: kAppName,
- findType: 'text,
- findWords: [what],
- cursor: theCursor,
- };
- AddArraySlot(results,theResult);
- end
- end
- end,
- usoup: nil,
- viewScrollUpScript:
- func()
- begin
- // we use local variables in case the call to Prev()
- // fails, and we avoid restoring the cursor
- local localCursor:= cursor:Clone();
- local localEntry:= localCursor:Prev();
- if localEntry then
- begin
- if dirty then
- :SaveToSoup();
- :SetTarget(localEntry);
- end
- else
- GetRoot():SysBeep()
- end,
- DeleteAnEntry:
- func(entry)
- // remove the entry from our soup,
- // adjust the target and the display
- // note: all of our methods are built
- // to handle a NIL Target
- begin
- EntryRemoveFromSoup(entry);
- local newTarget:= cursor:Next();
- if not newTarget then
- newTarget:= cursor:Prev();
- :SetTarget(newTarget);
- end,
- declareSelf: 'base,
- viewSetupFormScript:
- func()
- begin
- uSoup := call kRegisterCardSoupFunc with
- (kSoupName,kSoupIndexes,kAppSymbol,kAppObject);
- cursor := Query(uSoup, {type: 'index,
- ValidTest: func(entry) begin
- return labelsFilter = '_all or
- entry.labels = labelsFilter; end});
- :SetupIdle(5000);
- :ResizeToFitScreen();
- TargetView:= self;
- end,
- DuplicateActionScript:
- func(entryToDuplicate, targetView)
- // copy the entry into our soup and
- // adjust the target and display
- begin
- if entryToDuplicate then
- begin
- local newEntry:= EntryCopy(entryToDuplicate, uSoup);
- :SetTarget(newEntry);
- AddUndoAction('UndoDuplicateEntry, [newEntry])
- end
- else
- GetRoot():SysBeep();
- end,
- dirty: nil,
- prefsEntry: nil,
- SetupRoutingSlip:
- func(fields)
- // required to support routing, this function stuffs
- // the slots of a frame passed to it by the system
- begin
- fields.title:= "Beamed GoodFormDatum:" && Target.text
- end,
- GetLastTargetFromPrefsID:
- func()
- // uses a soup query to get an entry using the old target's _uniqueID
- begin
- local localCursor := Query(uSoup, {
- type: 'index,
- validTest: func(entry)
- begin
- return entry._uniqueID = prefsEntry;
- end});
- return localCursor:Entry();
- end,
- viewclass: 74,
- MakeNewEntry:
- func()
- // Create a new soup entry, the labels slot is used to support filing
- begin
- if dirty then
- :SaveToSoup();
- local newEntry := Clone(kDefaultEntry);
- newEntry.labels := if labelsFilter = '_all then nil else labelsFilter ;
- uSoup:AddToDefaultStore(newEntry);
- newEntry;
- end,
- FindSoupExcerpt:
- func(entry, finder)
- begin
- inherited:FindSoupExcerpt(entry, finder);
- // call inherited version
- end,
- UpdateFieldsFromEntry:
- func(entry)
- // Update the view field with the entry from the soup
- // and if the entry is nil, display a notification
- begin
- if entry then
- begin
- inputField:Show();
- itemLabel:Show();
- SetValue(inputField,'text, Clone(entry.text));
- SetValue(infoField, 'text, "Entry No:" && entry._uniqueID)
- end
- else
- begin
- inputField:Hide();
- itemLabel:Hide();
- // Should really differentiate between no entries in folder
- // and no entries at all (i.e., labelsFilter <> '_all and
- // no entries at all versus labelsFilter <> '_all and
- // entries in another folder
- SetValue(infoField,'text,
- if labelsFilter = '_all then
- "There is no Data to display."
- else
- "There is no Data in this folder");
- end;
- :SetDirty(nil);
- end,
- debug: "GoodFormBase",
- undoDeleteEntry:
- func(entry)
- begin
- uSoup:AddToDefaultStore(entry);
- :SetTarget(entry);
- end,
- targetView: nil,
- ResizeToFitScreen:
- func()
- // this function uses the global function, GetAppParams()
- // to get the current size of the screen and adjusts our
- // base view's size accordingly
- begin
- local params:= GetAppParams();
- self.viewBounds := RelBounds(
- params.appAreaLeft,
- params.appAreaTop,
- MIN(kMaxApplicationWidth, params.appAreaWidth),
- MIN(kMaxApplicationHeight, params.appAreaHeight)
- );
- end,
- entryRoutingFrame:
- {
- zap: {
- Title: "Beam Datum",
- routeForm: 'zapSlip,
- },
-
- separator: NIL,
-
- delete: {
- title: "Delete",
- routeScript: 'DeleteActionScript,
- },
-
- duplicate: {
- title: "Duplicate",
- routeScript: 'DuplicateActionScript,
- },
-
- card: ROM_CardAction,
- }
- };
-
- InfoLabel := /* child of GoodFormBase */
- {text: "Status:",
- viewBounds: {left: 5, top: 30, right: 90, bottom: 45},
- _proto: protoStaticText,
- debug: "InfoLabel"
- };
-
-
-
- infoField := /* child of GoodFormBase */
- {
- text:
- "Tap the up and down arrows to scroll in the database. Tap the \"New\" button to create a new record."
- ,
- viewBounds: {left: 0, top: 0, right: 220, bottom: 55},
- viewFormat: 336,
- viewJustify: 10368,
- _proto: protoStaticText,
- debug: "infoField"
- };
- // View infoField is declared to GoodFormBase
-
-
-
- ItemLabel := /* child of GoodFormBase */
- {text: "Current Item:",
- viewBounds: {left: 0, top: 12, right: 85, bottom: 27},
- viewJustify: 8398976,
- _proto: protoStaticText,
- debug: "ItemLabel"
- };
- // View ItemLabel is declared to GoodFormBase
-
-
-
- inputField := /* child of GoodFormBase */
- {viewFlags: 6657,
- viewFormat: 12625,
- viewlinespacing: 20,
- viewFont: userFont18,
- viewBounds: {left: 0, top: 0, right: 220, bottom: 102},
- viewJustify: 10368,
- viewChangedScript:
- func(slot, view)
- begin
- :SetDirty(true);
- end,
- viewclass: 81,
- debug: "inputField"
- };
- // View inputField is declared to GoodFormBase
-
-
-
- _view000 := /* child of GoodFormBase */ {_proto: protoStatus};
-
- _view001 := /* child of _view000 */ {_proto: protoActionButton};
-
-
-
- _view002 := /* child of _view000 */
- {viewBounds: {left: -23, top: 2, right: -6, bottom: 15},
- _proto: protoFilingButton
- };
-
-
-
- New := /* child of _view000 */
- {text: "New",
- buttonClickScript:
- func()
- begin
- :SetTarget(:MakeNewEntry());
- end,
- viewBounds: {left: 28, top: 2, right: 54, bottom: 15},
- viewJustify: 8388614,
- _proto: protoTextButton,
- debug: "New"
- };
-
- // After Script for "New"
- thisView := New;
- // set the bounds of the button so that it is to the right
- // of the clock and the correct height for the status bar
- thisView.viewBounds := ButtonBounds(-(thisView.viewBounds.right - thisView.viewBounds.left));
-
-
-
-
-
- folderTab := /* child of GoodFormBase */
- {_proto: protoFolderTab, debug: "folderTab"};
- // View folderTab is declared to GoodFormBase
-
-
-
-
-
-
-
- // ---- Beginning of section for non used Layout files ----
-
- // End of output